package com.foreveross.eimpc.web.controller;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.foreveross.eimpc.web.constants.FileType;
import com.foreveross.eimpc.web.service.FileOperationsManager;
import com.foreveross.eimpc.web.vo.ProgressVO;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * 文件操作 图片文件上传，下载 Created by yanyuan on 2014/11/24.
 */
@Controller
@RequestMapping("/fileOperations")
public class FileOperationsController extends BaseController {

	private Logger logger = LoggerFactory
			.getLogger(FileOperationsController.class);
	/**
	 * 文件上传成功，返回对象的key
	 */
	public static final String FILE_UPLOAD_RETURN_KEY = "TFS_FILE_NAME";

	/**
	 * 文件上传
	 * 
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "uploadStreamMd5.do", method = RequestMethod.POST)
	public Map<String, Object> uploadStreamMd5(HttpServletRequest request) {
		Map<String, Object> returnMap = new HashMap<String, Object>();
		String file = request.getParameter("uploadFile");
		byte[] fileBytes = new Base64().decode(base64StringFormat(file));
		String suffix = request.getParameter("suffix");
		HttpSession session = request.getSession(true);
		JSONObject user = (JSONObject) session.getAttribute("user");
		String result = null;
		FileType type = FileType.getFileType(suffix);
		String uploadFileType = null;
		if (type == FileType.IMG) {
			result = FileOperationsManager.uploadImg(suffix, fileBytes,
					user.getString("access_token"));
			uploadFileType = FileType.IMG.toString();
		} else {
			String fileName = request.getParameter("fileName");
			result = FileOperationsManager.uploadStreamMd5(fileName, suffix,
					fileBytes, user.getString("access_token"));
			uploadFileType = FileType.FILE.toString();
		}
		JSONObject jsonObject = JSON.parseObject(result);
		returnMap.put("mediaId", jsonObject.getString(FILE_UPLOAD_RETURN_KEY));
		returnMap.put("uploadFileType", uploadFileType);
		returnMap.put("result", "success");
		return returnMap;
	}

	/**
	 * 文件上传
	 * 
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "upload.do", method = RequestMethod.POST)
	public Map<String, Object> upload(@RequestParam MultipartFile[] files,
			HttpServletRequest request) {
		Map<String, Object> returnMap = new HashMap<String, Object>();
		String thumb = "";
		try {
			MultipartFile file = files[0];
			byte[] fileBytes = file.getBytes();
			logger.info("fileBytes:" + fileBytes.length);

			String suffix = file.getOriginalFilename().substring(
					file.getOriginalFilename().lastIndexOf(".") + 1);
			suffix = suffix.toLowerCase();
			logger.info("suffix:" + suffix);

			HttpSession session = request.getSession(true);
			JSONObject user = (JSONObject) session.getAttribute("user");
			logger.debug("user:" + user.toJSONString());
			String result = null;
			FileType type = FileType.getFileType(suffix);
			String uploadFileType = null;
			if (type == FileType.IMG) {
				result = FileOperationsManager.uploadImg(suffix, fileBytes,
						user.getString("access_token"));
				uploadFileType = FileType.IMG.toString();
				thumb = generateThumb(fileBytes);
				logger.info("thumb:" + thumb.length());
			} else {
				String fileName = file.getOriginalFilename().substring(0,
						file.getOriginalFilename().indexOf("."));
				result = FileOperationsManager.uploadStreamMd5(fileName,
						suffix, fileBytes, user.getString("access_token"));
				uploadFileType = FileType.FILE.toString();
			}
			JSONObject jsonObject = JSON.parseObject(result);
			logger.info("upload result=" + result);
			returnMap.put("mediaId",
					jsonObject.getString(FILE_UPLOAD_RETURN_KEY));
			returnMap.put("uploadFileType", uploadFileType);
			returnMap.put("thumb", thumb);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("文件上传失败！");
		}
		returnMap.put("result", "success");
		return returnMap;
	}

	// 增加文件进度数据
	@ResponseBody
	@RequestMapping(value = "getProgress.do", method = RequestMethod.GET)
	public Map<String, Object> getProgress(HttpServletRequest request) {
		Map<String, Object> returnMap = new HashMap<String, Object>();
		String  name = request.getParameter("s_filename");
		ProgressVO ps = (ProgressVO) request.getSession().getAttribute(
				"upload_ps"+name);
		if (ps == null) {
			ps  =new ProgressVO();
			ps.setProg(0);
			returnMap.put("result", "success");
			returnMap.put("progressvo", ps);
			return returnMap;
		}

		long read = ps.getpBytesRead();
		if (read != 0) {
			long size = ps.getpContentLength();
			long prog = read * 100 / size;
			ps.setProg(prog);
			logger.info("new  ->:" + read);
			logger.info("size ->:" + size);
			logger.info("prog ->:" + prog);
		} else {
			ps.setProg(0);
		}
		returnMap.put("result", "success");
		returnMap.put("progressvo", ps);
		return returnMap;
	}

	public String generateThumb(byte[] jpgs) {
		String res = "";
		ByteArrayOutputStream baos = null;
		BufferedOutputStream bos = null;
		try {
			InputStream is = new ByteArrayInputStream(jpgs);

			Image src = ImageIO.read(is); // 构造Image对象
			int oldWidth = src.getWidth(null); // 得到源图宽
			int oldHeight = src.getHeight(null);// 得到源图高
			logger.debug("oldWidth=" + oldWidth);
			logger.debug("oldHeight=" + oldHeight);
			float divWidth = 120f; // 限制宽度为200
			int newWidth = 110; // 缩略图宽,
			int newHeight = 0; // 缩略图高
			float tmp;
			if (oldWidth > newWidth) {
				tmp = oldWidth / divWidth;
				newWidth = Math.round(oldWidth / tmp);// 计算缩略图高
				newHeight = Math.round(oldHeight / tmp);// 计算缩略图高
			} else {
				newWidth = oldWidth;
				newHeight = oldHeight;
			}

			int imageHeight = 85;
			int imageWidth = 100;
			BufferedImage bufferedImage = new BufferedImage(imageWidth,
					imageHeight, BufferedImage.TYPE_INT_RGB);

			Graphics2D graphics2D = (Graphics2D) bufferedImage.createGraphics();
			graphics2D.setBackground(Color.WHITE);
			graphics2D.clearRect(0, 0, imageWidth, imageHeight);
			bufferedImage.getGraphics().drawImage(src, 0, 0, newWidth,
					newHeight, null); // 绘制缩小后的图

			baos = new ByteArrayOutputStream();
			bos = new BufferedOutputStream(baos);
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
			encoder.encode(bufferedImage); // 近JPEG编码
			byte[] rtn = baos.toByteArray();

			for (int i = 0; i < rtn.length; i++) {
				res += rtn[i] + ",";
			}
		} catch (IOException e) {
			logger.error("生成缩略图异常", e);
		} finally {
			try {
				baos.close();
				bos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return res;
	}

	public static void genFile(byte[] bfile, String filePath, String fileName) {
		BufferedOutputStream bos = null;
		FileOutputStream fos = null;
		File file = null;
		try {
			File dir = new File(filePath);
			if (!dir.exists() && dir.isDirectory()) {// 判断文件目录是否存在
				dir.mkdirs();
			}
			file = new File(filePath + File.separator + fileName);
			fos = new FileOutputStream(file);
			bos = new BufferedOutputStream(fos);
			bos.write(bfile);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

}
